﻿/*
	Copyright (C) 2019 Zongming Liu <1849059316@qq.com>

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License along
	with this program; if not, write to the Free Software Foundation, Inc.,
	51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#ifndef Render_h__
#define Render_h__

#include "../base/Common.h"
#include "../base/Color.h"
#include "../base/Vector.h"
#include "../base/VertexType.h"
#include "../utility/Singleton.h"

#include "IDirectRender.h"
#include "IRender.h"
#include "RenderCommand.h"
#include "IBatDrawCommand.h"
#include <cstring>

namespace SkyEngine2d
{
	class RenderQueue;
	class RenderCommand;
	class Program;
	class Material;
	class TrianglesCommand;

	/*!
	 \brief 渲染
	 \details
	*/
	class Render
		:public IDirectRender, public IRender
	{
	public:

		//! 设置清除目标时的颜色
		virtual void setClearColor(const Color4f& clear_color) override;

		//! 是否初始化 
		virtual bool isInit() const override;

		//! 获取当前帧的DrawCall 次数
		virtual int getDrawCallCount() override;

		//! 获取当前帧的绘制命令总数
		virtual int getDrawCmdCount() override;

		//! 获取当前帧绘制的顶点总数
		virtual int getVertexCount() override;

		//! 添加渲染命令 
		virtual void addRenderCommand(RenderCommand* cmd) override;

		//开始渲染
		virtual void renderBegin();
		//结束渲染
		virtual HRESULT renderEnd();
		//每帧调用其进行渲染
		virtual void render() override;

		virtual IDirectRender* getDirectRender() override;

		//! 析构
		~Render();

		virtual ID3D11Device* getD3dDevice() override;


		virtual ID3D11DeviceContext* getD3dDeviceContext() override;

		virtual ID3D11RenderTargetView* getD3dRenderTargetView() override;

		virtual IDXGISwapChain1* getD3dSwapChain() override;

		virtual ID3D11DepthStencilView* getD3dDepthStencilView() override;

		virtual void ClearDirect3D() override;

		virtual void onResize(HWND hwnd, UINT w, UINT h) override;

		virtual ID2D1RenderTarget* getD2dRenderTarget() override;

		virtual float getDpi() override;

		bool init(HWND hwnd, UINT w, UINT h);

		Render();
	private:
		void processRenderCmd(RenderCommand* cmd);
		void batchDrawTriangles();
		void clearBathDrawTriangles();
		void fillVerticesAndIndex(IBatDrawCommand* cmd);

	private:
		class Impl;
		bool m_isInit;
		std::unique_ptr<Impl>  m_d3dData;
		std::unique_ptr<RenderQueue> m_renderQueue;
		FLOAT m_clearColor[4];

		///////////////////////////////////////////////////
		//自动批处理
		//////////////////////////////////////////////////
		RenderCommand::Type  m_lastCmdtype;
		//可以批处理的三角形指令队列
		std::vector<IBatDrawCommand*> m_randerTrianglesQueue;
		//上一个命令的材质
		Material* m_lastCmdMatrix;

		struct VIBuffer;
		VIBuffer* m_vertexIndexBuffer;

		//顶点缓存的填充数量
		int m_fillVertexCount;
		//索引缓存的填充数量
		int m_fillIndexCount;

		//本次批处理的索引总数量
		int m_currentBatAllIndexCount;
		//本次批处理的顶点总数量
		int m_currentBatAllVertexCount;

		//当前渲染批次的顶点数
		int m_currentBatVertexCount;
		//draw call 数量
		int m_drawCall;
		//命令数
		int m_drawCmdCount;
		//顶点数
		int m_vertexCount;

		struct TrianglesBat
		{
			IBatDrawCommand* cmd;
			int	indexCount;
			int startVertexPos;
			int startIndexPos;
		};
		//批处理队列
		std::vector<TrianglesBat> m_batDrawVector;
	};

}

#endif // Render_h__